#include "ZZ_IO.h"
#include <wiringSerial.h>
#include <unistd.h>
#include <iostream>
#include <wiringPi.h>
#include <cjson/cJSON.h>


using std::cout;

void zz_io::switchRelay(int relay, int status)
{
	int fd;
	fd = serialOpen("/dev/ttyUSB0", 38400);
	if (fd == -1)
	{
		cout << "无法打开串口";
		return;
	}
		
	if (relay == 0)
	{
		if (status >= 1)
		{
			serialFlush(fd);
			write(fd, ZZ_IO_OPEN_RELAY_0, sizeof(ZZ_IO_OPEN_RELAY_0));
		}
		else if(status == 0)
		{
			serialFlush(fd);
			write(fd, ZZ_IO_CLOSE_RELAY_0, sizeof(ZZ_IO_CLOSE_RELAY_0));
		}
	}
	else if(relay == 1)
	{
		if (status >= 1)
		{
			serialFlush(fd);
			write(fd, ZZ_IO_OPEN_RELAY_1, sizeof(ZZ_IO_OPEN_RELAY_1));
		}
		else if (status == 0)
		{
			serialFlush(fd);
			write(fd, ZZ_IO_CLOSE_RELAY_1, sizeof(ZZ_IO_CLOSE_RELAY_1));
		}
	}
	
	serialClose(fd);
}

void zz_io::getRelayStatus()
{
	int fd = serialOpen("/dev/ttyS0", 9600);
	uint8_t  buf[8] = { 0 };
	if (fd == -1)
	{
		cout << "无法打开串口";
		return;
	}
	serialFlush(fd);
	write(fd, ZZ_IO_QUERY, sizeof(ZZ_IO_QUERY));
	//memset(buffer, '\0', sizeof(buffer));
	delay(100);
	int readByte = read(fd, buf, sizeof(buf));
	
	if (readByte > 0)
	{
		//TODO: 校验


		if (buf[3] & 0x01)
		{
			relay0_status = 1;
		}
		else
		{
			relay0_status = 0;

		}
		if (buf[3] & 0x02)
		{
			relay1_status = 1;
		}
		else
		{
			relay1_status = 0;
		}
		
	}
	serialClose(fd);
}

zz_io::zz_io(int Device_ID) :buffer("zz_io_204.db"), relay0_status(0), relay1_status(0), Device_ID(Device_ID)
{
	

}

void zz_io::updateBuffer()
{
	if (buffer.isTableExist(ZZ_IO_204_REALY_STATUS))
	{
		//getRelayStatus(NULL);
		cJSON* relayObj = cJSON_CreateObject();
		cJSON* relay0_status_item = cJSON_CreateBool(relay0_status ? 1 : 0);
		cJSON* relay1_status_item = cJSON_CreateBool(relay1_status ? 1 : 0);
		cJSON_AddItemToObject(relayObj, "relay_0", relay0_status_item);
		cJSON_AddItemToObject(relayObj, "relay_1", relay1_status_item);

		buffer.writeDataJsonToTable(ZZ_IO_204_REALY_STATUS,cJSON_Print(relayObj));
		cJSON_free(relayObj);
		cJSON_free(relay0_status_item);
		cJSON_free(relay1_status_item);
	}
	else
	{
		buffer.createDataTable(ZZ_IO_204_REALY_STATUS);
		updateBuffer();
	}
}

void zz_io::operate()
{
	if (buffer.isTableExist(ZZ_IO_204_OPERATION))
	{
		std::string operation;
		while (buffer.getOperation(ZZ_IO_204_OPERATION, operation))
		{
			cout << operation << std::endl;
			cJSON* operationObj = cJSON_Parse(operation.c_str());
			cJSON* relay0StatusItem = cJSON_GetObjectItemCaseSensitive(operationObj, "relay_0");
			cJSON* relay1StatusItem = cJSON_GetObjectItemCaseSensitive(operationObj, "relay_1");
			if (relay0StatusItem)
			{
				if (relay0StatusItem->valueint)
				{
					switchRelay(0, 1);
				}
				else
				{
					switchRelay(0, 0);
				}
			}
			if (relay1StatusItem)
			{
				if (relay1StatusItem->valueint)
				{
					switchRelay(1, 1);
				}
				else
				{
					switchRelay(1, 0);
				}
			}
			operation.clear();
			cJSON_free(operationObj);
			cJSON_free(relay0StatusItem);
			cJSON_free(relay1StatusItem);
		}
	}
	else
	{
		buffer.createOperaionTable(ZZ_IO_204_OPERATION);
		operate();
	}
}